/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.lucava.boatskeeper.client.presenter.boat;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HasValue;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.Panel;
import gwtupload.client.IUploadStatus.Status;
import gwtupload.client.IUploader;
import gwtupload.client.IUploader.UploadedInfo;
import gwtupload.client.MultiUploader;
import gwtupload.client.PreloadedImage;
import gwtupload.client.PreloadedImage.OnLoadPreloadedImageHandler;
import java.util.List;
import net.customware.gwt.dispatch.client.DispatchAsync;
import net.customware.gwt.presenter.client.EventBus;
import net.customware.gwt.presenter.client.place.Place;
import net.customware.gwt.presenter.client.place.PlaceRequest;
import net.customware.gwt.presenter.client.widget.WidgetDisplay;
import org.lucava.boatskeeper.client.MainLayout;
import org.lucava.boatskeeper.client.PlaceMapper;
import org.lucava.boatskeeper.client.event.EditCancelledEvent;
import org.lucava.boatskeeper.client.event.UpdatedEvent;
import org.lucava.boatskeeper.client.presenter.ViewPresenter;
import org.lucava.boatskeeper.shared.Boat;
import org.lucava.boatskeeper.shared.BoatImage;
import org.lucava.boatskeeper.shared.Category;
import org.lucava.boatskeeper.shared.rpc.boat.AddBoat;
import org.lucava.boatskeeper.shared.rpc.boat.AddBoatResult;
import org.lucava.boatskeeper.shared.rpc.boat.GetBoat;
import org.lucava.boatskeeper.shared.rpc.boat.GetBoatResult;
import org.lucava.boatskeeper.shared.rpc.boat.GetCategories;
import org.lucava.boatskeeper.shared.rpc.boat.GetCategoriesResult;
import org.lucava.boatskeeper.shared.rpc.boat.SaveBoat;
import org.lucava.boatskeeper.shared.rpc.boat.SaveBoatResult;

/**
 *
 * @author glenn
 */
public class EditBoatPresenter extends ViewPresenter<EditBoatPresenter.Display> {

    public interface Display extends WidgetDisplay {

        HasClickHandlers getSaveButton();

        HasClickHandlers getCancelButton();

        public HasValue<String> getDisplayName();

        public Integer getCategoryValue();

        public ListBox getCategoryList();

        public MultiUploader getUploader();

        public Panel getImagePanel();
    }
    private final OnLoadPreloadedImageHandler showImage = new OnLoadPreloadedImageHandler() {
        @Override
        public void onLoad(PreloadedImage image) {
            image.setWidth("75px");
            display.getImagePanel().clear();
            display.getImagePanel().add(image);
        }
    };
    public static Place PLACE;
    private Boat boat;
    private List<Category> categories;

    public EditBoatPresenter(DispatchAsync dispatcher, EventBus eventBus, Display display) {
        super(dispatcher, eventBus, display);
        bind();
    }

    @Override
    protected void onBind() {


        fetchCategories();
        display.getSaveButton().addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                doSave();
            }
        });

        display.getCancelButton().addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                boat = null;
                display.getUploader().cancel();
                display.getUploader().reset();
                display.getImagePanel().clear();
                eventBus.fireEvent(new EditCancelledEvent(PlaceMapper.LIST_BOAT));
            }
        });



        display.getUploader().addOnFinishUploadHandler(new IUploader.OnFinishUploaderHandler() {
            @Override
            public void onFinish(IUploader uploader) {
                if (uploader.getStatus() == Status.SUCCESS) {

                    new PreloadedImage(uploader.fileUrl(), showImage);

                    // The server sends useful information to the client by default
                    UploadedInfo info = uploader.getServerInfo();
                    System.out.println("File name " + info.name);
                    System.out.println("File content-type " + info.ctype);
                    System.out.println("File size " + info.size);

                    // You can send any customized message and parse it 
                    System.out.println("Server message " + info.message);
                }
            }
        });




    }

    protected void doSave() {
        if (boat == null) {
            boat = new Boat();
        }

        boat.setDisplayName(display.getDisplayName().getValue());
        boat.setCategoryId(display.getCategoryValue());
        boat.setBoatImage(new BoatImage(display.getUploader().getBasename(), display.getUploader().fileUrl()));

        if (boat.getId() != null) {
            getDispatcher().execute(new SaveBoat(boat), new AsyncCallback<SaveBoatResult>() {
                @Override
                public void onSuccess(SaveBoatResult result) {
                    eventBus.fireEvent(new UpdatedEvent(PlaceMapper.LIST_BOAT, result.getBoat()));
                }

                @Override
                public void onFailure(Throwable caught) {
                    Window.alert("Error updating boat");
                }
            });
        } else {
            getDispatcher().execute(new AddBoat(boat), new AsyncCallback<AddBoatResult>() {
                @Override
                public void onSuccess(AddBoatResult result) {
                    eventBus.fireEvent(new UpdatedEvent(PlaceMapper.LIST_BOAT, result.getBoat()));
                }

                @Override
                public void onFailure(Throwable caught) {
                    caught.printStackTrace();
                    Window.alert("Error Adding boat");
                }
            });
        }
        display.getUploader().reset();
        display.getImagePanel().clear();
        boat = null;
    }

    private void getBoat(Integer id) {
        getDispatcher().execute(new GetBoat(id), new AsyncCallback<GetBoatResult>() {
            @Override
            public void onSuccess(GetBoatResult result) {
                boat = result.getBoat();
                refreshDisplay();

            }

            @Override
            public void onFailure(Throwable caught) {
                // TODO Auto-generated method stub
            }
        });

    }

    private void fetchCategories() {
        getDispatcher().execute(new GetCategories(), new AsyncCallback<GetCategoriesResult>() {
            @Override
            public void onSuccess(GetCategoriesResult result) {
                categories = result.getCategoryList();
            }

            @Override
            public void onFailure(Throwable caught) {
                System.out.println(caught.getMessage());
                Window.alert(caught.getMessage());
            }
        });
    }

    @Override
    protected void onPlaceRequest(PlaceRequest request) {

        String boatId = request.getParameter("id", null);
        fetchCategories();
        if (boatId != null) {
            getBoat(Integer.parseInt(boatId));
        } else {
            boat = null;
            refreshDisplay();
        }
    }

    @Override
    public void refreshDisplay() {
        if (boat != null) {
            Integer selectedIndex = 0;
            display.getDisplayName().setValue(boat.getDisplayName());
            for (Category cat : categories) {
                display.getCategoryList().addItem(cat.getDisplayName(), cat.getId().toString());
                if (cat.getId().equals(boat.getCategoryId())) {
                    selectedIndex = display.getCategoryList().getItemCount() - 1;
                }
            }
            display.getCategoryList().setSelectedIndex(selectedIndex);
            if (boat.getBoatImage() != null) {
                new PreloadedImage(boat.getBoatImage().getUrl(), showImage);
            }


        } else {

            display.getDisplayName().setValue(null);
            for (Category cat : categories) {
                display.getCategoryList().addItem(cat.getDisplayName(), cat.getId().toString());
            }
            display.getCategoryList().setSelectedIndex(0);
        }



    }

    @Override
    public Place getPlace() {
        return PLACE;
    }

}
